%:- use_module(library(clpr)).
:- use_module(library('clp/bounds')).

:- consult(conditions_3br).
:- consult(arr_fnc).

% path(N brigade, N from, N to, path time)
path(Br,0,B,T) :- 
	at(Br,AT), 
	ht(Br,B,HT), 
	T #= AT + HT.
%	write(0 -> B : T),nl.

path(Br,A,B,T) :- 
	ht(Br,A,HT1), 
	ht(Br,B,HT2), 
	T #= HT1 + HT2.
%	write(A -> B: T), nl.

% store path to list [A,B,T]
step(Br,A,B,T,[A,B,T]) :- path(Br,A,B,T).

% route(N brigade, N from, N to, path time, Ps - edges list, HC - total quantity of patients delivered to each hospital before this route, HCnew - total quantity of patients delivered to each hospital after this route, Pq - number of patients)
% the path through points: X,Z,Y
route(_,X,X,0,[],HC,HC,0).

route(Br,X,Y,T,Ps,HC,HCnew,Pq) :- 
	%write('3333   '), nl,
	Pq #> 0, Pq1 #= Pq - 1,
	route(Br,X,Z,T1,Ps1,HC,HC1,Pq1),
	step(Br,Z,Y,T2,Ps2),
	inc_arr(Y,_,HC1,HCnew),
	nth1(Y,HCnew,Hc1),
	hc(Y,Hc2),
	Hc1 =< Hc2,
	T #= T1 + T2,
	solution(BT,_,_),
	T < BT,
	Ps = [Ps1|Ps2].

%Finds routes for all brigades from BrARR list. PsARR is an ald list of routes. Every new road for next brigade from BrARR enriches PsARR and returns PsARRnew. TARR is a list of times, spended by each brigade for its routes. HF is an array? which showes filling of hospitals. PQARR is a list with number of patients for each brigade.
routes([],PsARR,PsARR,TARR,TARR,HF,HF,_).

routes(BrARR,PsARR,PsARRnew,TARR,TARRnew,HF,HFnew,PQARR) :-
	BrARR = [Br|BrARR1],
	nth1(Br,PQARR,PQ1),
	%write(Br),nl,
	route(Br,0,_,T1,Ps1,HF,HF1,PQ1),
	set_arr(Br,PsARR,[#,Br|Ps1],PsARR2,_),
	set_arr(Br,TARR,[T1],TARR1,_),
	%write(TARR1),nl,
	%write(PsARR2),nl,
	%write(HF1),nl,
	routes(BrARR1,PsARR2,PsARRnew,TARR1,TARRnew,HF1,HFnew,PQARR).
	

%mutual - finds a solution for number of brigades and rewrites it to database, if new solution is better then old, saved in database.
mutual:- 
        problem_size(Br,H,PQ),
	create_arr(HC1,H),
	create_arr(TARR,Br),
	length(PsARR,Br),
	init_arr(PsARR,[]),
	length(PQARR,Br),
	PQARR in 0..PQ,
	sum(PQARR,#=,PQ),
	%nth1(1,PQARR,PQ1),
	%nth1(2,PQARR,PQ2),
	
	numlist(1,Br,BrARR),
	%write('BrARR'),write(BrARR),nl,
	routes(BrARR,PsARR,Ps,TARR,TARR2,HC1,HC,PQARR),
	%route(1,0,_,T1,Ps1,HC1,HC2,PQ1),
	%set_arr(1,TARR,T1,TARR1,_),	
	%set_arr(1,PsARR,Ps1,PsARR1,_),
	
	%route(2,0,_,T2,Ps2,HC2,HC,PQ2),
	%set_arr(2,TARR1,T2,TARR2,_),
	%set_arr(2,PsARR1,Ps2,Ps,_),
	
	msort(TARR2,TARRsort),
	last(TARRsort,T),
	%Ps = [Ps1, #|Ps2],
	%T #= max(T1,T2),
		
	retract(solution(_,_,_)),
	asserta(solution(T,Ps,HC)),
	fail.

% solve(TE - total time, PS - list of routs for brigades ([route of Br1 # rout of Br2]), HC - total quantity of patients delivered to each hospital)
% example: solve(TE,PS,H).
solve(TE,PS,HC):- 
	asserta(solution(100000,ps,hc)),
	not(mutual),
	retract(solution(TE,Ps,Hc)),
	flatten(Ps,PS),
	flatten(Hc,HC).
